import React, { useEffect, useMemo, useState } from "react"
import { View, Input, Button, Picker, Text, Image } from "@tarojs/components"
import userInfo from "@/store/user";
import account from "@/store/account";
import category from '@/store/categorys';
import { AtModal, AtModalContent, AtModalAction, AtModalHeader } from "taro-ui"
import { accountMemberType, billType, categoryType } from "@/types";
import { MoneyFormat } from "@/utils/format";
import { billTypes } from "@/dict";
import { avatarUrlFormat, HideLoading, ShowFail, ShowLoading, ShowToast, VibrateShort } from "@/utils";
import http from "@/request";
import user from "@/store/user";
import Taro from "@tarojs/taro";
import CategorySelecter from "../categorySelecter";

import './index.scss'

const BillForm: React.FC<{
    visible: boolean,
    // 是否在初次进来的时候自动识别一次
    autoIdentify?: boolean,
    bill?: billType,
    onClose?: () => void,
    onSure?: (bill: billType) => void
    // 自定义的保存逻辑,传入后就不会执行默认的保存
    onSava?: (bill: billType) => void
}> = React.memo(({ bill, visible, onClose, onSure, onSava, autoIdentify }) => {

    const [billInfo, setBillInfo] = useState<billType>({
        amount: 0,
        note: '',
        type: 0,
        payeeId: 0,
        date: '',
        accountId: account.activeAccount?.id,
        accountName: account.activeAccount?.name,
        userId: userInfo.info?.id
    })
    const [showMore, setShowMore] = useState(false)
    const [amountStr, setAmountStr] = useState('')
    // 强制刷新使用
    const [renderKey, setRenderKey] = useState(new Date().getTime())
    const [errorMsg, setErrorMsg] = useState('')
    const [categoryVisible, setCategoryVisible] = useState(false)

    const amountInput = (e) => {
        setAmountStr(MoneyFormat(e.target.value))
        setRenderKey(new Date().getTime())
    }

    const onInputChange = (e, key) => {
        setErrorMsg('')
        let value = e.target.value
        setBillInfo({
            ...billInfo,
            [key]: value
        })
    }

    const getCategoryName = (categoryId) => {
        const item = (category.categoryList || []).find(item => Number(item.id) === Number(categoryId))
        return item?.name || ''
    }

    const accountChange = (e) => {
        const index = e.target.value
        setBillInfo({
            ...billInfo,
            accountId: account.accountList[index].id,
            accountName: account.accountList[index].name
        })
    }
    //  当前选中账本
    const getAccountIndex = useMemo(() => {
        return (account.accountList || []).findIndex(item => Number(item.id) === Number(billInfo.accountId))
    }, [billInfo.accountId, account.accountList])

    const getAccountItem = useMemo(() => {
        return (account.accountList || []).find(item => Number(item.id) === Number(billInfo.accountId)) || { members: [] }
    }, [billInfo.accountId, account.accountList])


    const onBillTypeChange = (e) => {
        setBillInfo({
            ...billInfo,
            type: billTypes[e.target.value].id
        })
    }

    const memberChange = (user: accountMemberType, key: string) => {
        setBillInfo({
            ...billInfo,
            [key]: user.userId
        })
    }

    const textRecognition = (billItem) => {
        setErrorMsg('')
        if (!billItem.note) {
            ShowToast('请输入账单备注')
            return
        }
        ShowLoading('解析中...')
        http.post('/bills/textRecognition', {
            ...billItem
        }).then(res => {
            const bill = res.data as billType
            setAmountStr(MoneyFormat(bill.amount))
            setBillInfo({
                ...billItem,
                category: bill.category,
                categoryName: getCategoryName(bill.category),
                type: bill.type
            })
        }).catch(err => {
            setErrorMsg(err.msg || '解析语句失败')
        }).finally(() => {
            HideLoading()
        })
    }

    const saveBill = () => {
        if (onSava) {
            onSava({
                ...billInfo,
                amount: Number(amountStr.replace(/,/g, '')) || 0
            })
        } else {
            ShowLoading('保存中...')
            const params = {
                ...billInfo,
                amount: Number(amountStr.replace(/,/g, '')) || 0
            }
            http.post('/bills/addOrUpdate', params).then(res => {
                if (res.data) {
                    onSure && onSure(res.data)
                    HideLoading()
                    // 编辑和未开启通知的不发
                    if (currentCountMember?.notice && !params.id) {
                        // 发送消息
                        sendMessage(params)
                    }
                } else {
                    ShowFail('创建账单失败！')
                }
            }).catch(err => {
                ShowFail(err.msg || '创建账单失败！')
            })
        }
    }

    useEffect(() => {
        if (bill) {
            setBillInfo({ ...bill })
            // 如果设置了自动识别一次，在有备注时生效
            if (bill.note && autoIdentify) {
                textRecognition(bill)
            }
            setAmountStr((bill.amount || bill.amount === 0) ? MoneyFormat(bill.amount) : '')
            setShowMore(false)
        }
    }, [bill])

    const [isHide, setIsHide] = useState(false)
    useEffect(() => {
        // 延迟隐藏避免窗口闪烁
        if (visible) {
            setIsHide(true)
        } else {
            setTimeout(() => {
                setIsHide(visible)
            }, 200)
        }
    }, [visible])


    const currentCountMember = useMemo(() => {
        return (account.activeAccount?.members || []).find(item => {
            return item.userId === user.info?.id
        })
    }, [account.activeAccount])

    const sendMessage = (billInfo: billType) => {
        const receiveUserIds = (account.activeAccount?.members || []).map(item => {
            return item.userId
        }).filter(id => {
            return id && (id !== user.info?.id)
        })
        if (receiveUserIds.length) {
            Taro.requestSubscribeMessage({
                tmplIds: ['sVAHeMtfha1SkZJRSdjwKUCeHpkMLIhIbKpVrF_nlPQ'],
                entityIds: [],
                success: () => {
                    http.post("/message/sendtemplateMsg", {
                        note: billInfo.note,
                        sendUserName: user.info?.userName,
                        receiveUserIds,
                        categoryName: billInfo.categoryName || '-',
                        amount: billInfo.amount
                    })
                },
                fail: (e) => {
                    console.log(e);
                }
            })
        }
    }

    useEffect(() => {
        const cur = (account.accountList || []).find(item => {
            return item.id === billInfo.accountId
        })
        billInfo.accountName = cur?.name
        setRenderKey(new Date().getTime())
    }, [showMore])


    Taro.useDidHide(() => {
        setCategoryVisible(false)
        onClose && onClose()
    })

    const categoryName = useMemo(() => {
        return (category?.categoryMap || {})[billInfo.category || '']?.name || ''

    }, [category.categoryMap, billInfo.category])

    const categorySelectFinish = (category: categoryType) => {
        setCategoryVisible(false)
        setBillInfo({
            ...billInfo,
            category: category.id,
            categoryName: category.name
        })
    }

    return <View>
        <AtModal isOpened={visible} closeOnClickOverlay={false}>
            <AtModalHeader>
                <View className="modal-title">新增账单</View>
            </AtModalHeader>
            <AtModalContent>
                {isHide ? <View className="bill-form-container font-size24">
                    <View className="flex-row" style={{ alignItems: 'flex-end' }}>
                        <View className="form-item-container flex1">
                            <View className="form-item-label first-item flex-row flex-item">
                                <View>账单说明</View>
                                <View className="flex1"></View>
                            </View>
                            {/* <Textarea autoHeight placeholder="请输入" className="form-input" value={billInfo?.note || ''} onInput={(e) => onInputChange(e, 'note')}></Textarea> */}
                            <Input className="form-input" placeholder-class="placeholder-style" placeholder="请输入" value={billInfo?.note || ''} onInput={(e) => onInputChange(e, 'note')}></Input>
                        </View>
                        <View className="ai-btn flex-column flex-center" onClick={() => textRecognition(billInfo)}>
                            <View className="name font-size24">AI</View>
                            <View className="name font-size20">解析</View>
                        </View>
                    </View>
                    {errorMsg ? <View className="error-msg font-size20">{errorMsg}</View> : null}
                    <View className="form-item-container">
                        <View className="form-item-label">账单金额</View>
                        <Input className="form-input"
                            placeholder-class="placeholder-style"
                            placeholder="请输入"
                            value={amountStr}
                            key={renderKey}
                            onBlur={amountInput}
                            onInput={() => VibrateShort()}
                            type="digit" ></Input>
                    </View>
                    <View className="form-item-container">
                        <View className="form-item-label">账单分类</View>
                        <View className="flex-row flex-item" onClick={() => setCategoryVisible(true)}>
                            {categoryName ?
                                <View className='form-input'>
                                    {categoryName}
                                </View> :
                                <View className="form-input form-no-data">请选择</View>}
                            <View className="flex1"></View>
                            <Text className="iconfont icon-base-right"></Text>
                        </View>
                    </View>
                    <View className="form-item-container">
                        <View className="form-item-label">收支类型</View>
                        <Picker mode='selector' value={billInfo.type} onChange={(e) => onBillTypeChange(e)} rangeKey="name" range={billTypes}>
                            <View className="flex-row flex-item">
                                {isNaN(Number(billInfo.type)) ?
                                    <View className="form-input form-no-data">请选择</View> :
                                    <View className="form-input">
                                        {billTypes[Number(billInfo.type)].name}
                                    </View>
                                }
                                <View className="flex1"></View>
                                <Text className="iconfont icon-base-right"></Text>
                            </View>
                        </Picker>
                    </View>
                    {
                        showMore ? <>
                            <View className="form-item-container">
                                <View className="form-item-label">账单日期</View>
                                <Picker mode='date' value={billInfo.date || ''} onChange={(e) => onInputChange(e, 'date')}>
                                    <View className="flex-row flex-item">
                                        {billInfo.date ?
                                            <View className="form-input">
                                                {billInfo.date}
                                            </View> :
                                            <View className="form-input form-no-data">请选择</View>}
                                        <View className="flex1"></View>
                                        <Text className="iconfont icon-base-right"></Text>
                                    </View>
                                </Picker>
                            </View>
                            <View className="form-item-container">
                                <View className="form-item-label">归属账本</View>
                                <Picker className="flex1"
                                    range={account.accountList}
                                    rangeKey="name"
                                    onChange={accountChange}
                                    value={getAccountIndex}>
                                    <View className="flex-row flex-item">
                                        {billInfo.accountName ?
                                            <View className="form-input">
                                                {billInfo.accountName}
                                            </View> :
                                            <View className="form-input form-no-data">请选择</View>}
                                        <View className="flex1"></View>
                                        <Text className="iconfont icon-base-right"></Text>
                                    </View>
                                </Picker>
                            </View>
                            <View className="form-item-container">
                                <View className="form-item-label">付款成员</View>
                                <View className="flex-row">
                                    {
                                        getAccountItem?.members?.map(item => {
                                            return <View key={item.id}
                                                onClick={_ => memberChange(item, 'userId')}
                                                className={'member-item flex-column flex-center' + (billInfo.userId === item.userId ? ' active' : '')}>
                                                <Image className="iconfont font-size32" src={avatarUrlFormat(item.avatarUrl)} mode="aspectFill"></Image>
                                                <text className="member-name font-size24 font-otw">{item?.userName}</text>
                                            </View>
                                        })
                                    }
                                </View>
                            </View>
                            {
                                billInfo.type === 2 ? <View className="form-item-container">
                                    <View className="form-item-label">收款成员</View>
                                    <View className="flex-row">
                                        {
                                            getAccountItem?.members?.map(item => {
                                                return <View key={item.id}
                                                    onClick={_ => memberChange(item, 'payeeId')}
                                                    className={'member-item font-size32 flex-column flex-center' + (billInfo.payeeId === item.userId ? ' active' : '')}>
                                                    <Image className="iconfont" src={avatarUrlFormat(item.avatarUrl)} mode="aspectFill"></Image>
                                                    <text className="member-name font-size24 font-otw">{item?.userName}</text>
                                                </View>
                                            })
                                        }
                                    </View>
                                </View> : ''
                            }
                        </> : null
                    }
                    <View className="show-more-btn font-size24 flex-row flex-center" onClick={() => setShowMore(!showMore)}>
                        <Text className="name">{showMore ? '收起' : '更多设置项'}</Text>
                        <Text className={'iconfont icon-base-down ' + (showMore ? ' expand' : '')}></Text>
                    </View>
                </View> : null}
            </AtModalContent>
            <AtModalAction>
                <Button onClick={onClose}>取消</Button>
                <Button onClick={saveBill}>确定</Button>
            </AtModalAction>
        </AtModal>
        <CategorySelecter
            show={categoryVisible}
            value={billInfo.category}
            onClose={() => setCategoryVisible(false)}
            onSure={categorySelectFinish}>
        </CategorySelecter>
    </View>
})
export default BillForm